package game;

import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;

import javax.swing.ImageIcon;

/**
 * @author patrick
 * 
 */
public class IceCube extends Thread {

    private String cube = "/images/cube_big.png";
    // private String aerial = "/images/aerial5.png";
    private String aerial = "/images/3aerial01.png";
    // private String fluid = "/images/fluid.png";
    private String fluid = "/images/fluid_big2.png";
    private String fluid2 = "/images/fluid2.png";
    private String fluid3 = "/images/fluid3.png";
    private String tropfen = "/images/tropfen_big.png";

    private Image[] aerialimages = new Image[7];
    private Image[] fluidImages = new Image[7];

    // private String aerial1 = "/images/aerial.png";
    // private String aerial2 = "/images/aerial2.png";
    // private String aerial3 = "/images/aerial3.png";
    // private String aerial4 = "/images/aerial4.png";
    // private String aerial5 = "/images/aerial5.png";
    // private String aerial6 = "/images/aerial6.png";

    private String aerial1 = "/images/3aerial01.png";
    private String aerial2 = "/images/3aerial02.png";
    private String aerial3 = "/images/3aerial03.png";
    private String aerial4 = "/images/3aerial04.png";
    private String aerial5 = "/images/3aerial05.png";
    private String aerial6 = "/images/3aerial01.png";
    private String aerial7 = "/images/3aerial02.png";

    private float dx;
    private float dy;
    private float x;
    private float y;
    private int width;
    private int height;
    private int panelWidth;
    private int panelHeight;
    private int timetofly;
    private boolean isMoving;
    private boolean groundContact;
    private Image image;
    private Image fluidImage;
    private int animationState;
    private Image dropImage;
    private int activeImage;

    private boolean slideLeft;
    private boolean slideRight;

    private int currentState;
    public static final int HARD = 0;
    public static final int FLUID = 1;
    public static final int AERIAL = 2;

    private GamePanel gamepanel;

    /**
     * return default cube (hard)
     * */
    public IceCube(GamePanel gp) {
	ImageIcon ii = new ImageIcon(this.getClass().getResource(cube));
	image = ii.getImage();
	fluidImage = new ImageIcon(this.getClass().getResource(fluid))
		.getImage();

	aerialimages[0] = new ImageIcon(this.getClass().getResource(aerial1))
		.getImage();
	aerialimages[1] = new ImageIcon(this.getClass().getResource(aerial2))
		.getImage();
	aerialimages[2] = new ImageIcon(this.getClass().getResource(aerial3))
		.getImage();
	aerialimages[3] = new ImageIcon(this.getClass().getResource(aerial4))
		.getImage();
	aerialimages[4] = new ImageIcon(this.getClass().getResource(aerial5))
		.getImage();
	aerialimages[5] = new ImageIcon(this.getClass().getResource(aerial6))
		.getImage();
	aerialimages[6] = new ImageIcon(this.getClass().getResource(aerial7))
		.getImage();

	fluidImages[0] = new ImageIcon(this.getClass().getResource(aerial1))
		.getImage();
	fluidImages[1] = new ImageIcon(this.getClass().getResource(aerial2))
		.getImage();
	fluidImages[2] = new ImageIcon(this.getClass().getResource(aerial3))
		.getImage();
	fluidImages[3] = new ImageIcon(this.getClass().getResource(aerial4))
		.getImage();
	fluidImages[4] = new ImageIcon(this.getClass().getResource(aerial5))
		.getImage();
	fluidImages[5] = new ImageIcon(this.getClass().getResource(aerial6))
		.getImage();
	fluidImages[6] = new ImageIcon(this.getClass().getResource(aerial7))
		.getImage();

	dropImage = new ImageIcon(this.getClass().getResource(tropfen))
		.getImage();

	width = image.getWidth(null);
	height = image.getHeight(null);

	x = 40;
	y = 30;
	slideLeft = false;
	slideRight = false;

	currentState = HARD;

	this.gamepanel = gp;
	this.isMoving = false;
	groundContact = false;
	this.start();

	animationState = 0;
	// set the startImage
	activeImage = 0;

	width = image.getWidth(null);
	height = image.getHeight(null);
    }

    public int getTimetofly() {
	return timetofly;
    }

    public void setTimetofly(int timetofly) {
	this.timetofly = timetofly;
    }

    public boolean isGroundContact() {
	return groundContact;
    }

    public void setGroundContact(boolean groundContact) {
	this.groundContact = groundContact;
    }

    public boolean isSlideLeft() {
	return slideLeft;
    }

    public void setSlideLeft(boolean slideLeft) {
	this.slideLeft = slideLeft;
    }

    public boolean isSlideRight() {
	return slideRight;
    }

    public void setSlideRight(boolean slideRight) {
	this.slideRight = slideRight;
    }

    /**
     * makes player fluid
     * */
    public void makeFluid() {
	updateAggregateChanges();
	currentState = FLUID;
	ImageIcon ii = new ImageIcon(this.getClass().getResource(fluid));
	image = ii.getImage();
	width = image.getWidth(null);
	height = image.getHeight(null);

	// translate the image,
	// you don't want to get stuck in the walls
	y -= height / 2;
	animationState = 0;

    }

    /**
     * makes player hard
     * 
     * @param noUpdate
     *            if true change won't be counted
     * */
    public void makeHard(boolean noUpdate) {

	// if there is no room above...don't to anything
	if (currentState == FLUID) {
	    Rectangle2D.Double testshape = new Rectangle2D.Double(x, y - 40,
		    40, 40);
	    if (gamepanel.checkCollisions(testshape))
		return;
	}

	if (!noUpdate)
	    updateAggregateChanges();

	ImageIcon ii = new ImageIcon(this.getClass().getResource(cube));
	image = ii.getImage();
	width = image.getWidth(null);
	height = image.getHeight(null);

	// translate the image,
	// you don't want to get stuck in the walls
	animationState = 0;

	if (currentState == FLUID)
	    y -= 40;
	currentState = HARD;
    }

    /**
     * makes player aerial
     * */
    public void makeAerial() {

	// if fluid, move a bit upwards, that no collision with floor occurs
//    	if (currentState == FLUID)
//    	    this.y = this.y - 40;

	// if there is no room above...don't to anything
	if (currentState == FLUID) {
	    Rectangle2D.Double testshape = new Rectangle2D.Double(x, y - 40,
		    40, 40);
	    if (gamepanel.checkCollisions(testshape))
		return;
	}

	updateAggregateChanges();
//	currentState = AERIAL;

	ImageIcon ii = new ImageIcon(this.getClass().getResource(aerial));
	image = ii.getImage();
	width = image.getWidth(null);
	height = image.getHeight(null);
	// timetofly = 300000;
	timetofly = 100000;
	animationState = 0;

	if (currentState == FLUID)
	    y -= 40;

	currentState = AERIAL;
    }

    /**
     * updates the image for animations, depending on state (fluid, aerial,
     * hard)
     */
    public void updateImage() {

	if (currentState == AERIAL) {
	    animationState++;
	    if (animationState < aerialimages.length)
		this.image = aerialimages[animationState];

	    else
		animationState = 0;
	}
	// geht nicht, kA warum?????
	if (currentState == FLUID) {
/*
	    	System.out.println(groundContact);
		if(!this.groundContact)
		    image = this.dropImage;
		else {
		    if(this.animationState < fluidImages.length){
			    image = this.fluidImages[animationState];
			    animationState++;
		    }
		    else{
			animationState=0;
			this.image = fluidImage; 
		    }
			
		}
		*/ 
	}
    }

    public void setDropImage() {
	this.image = dropImage;
    }

    public void setFluidImage() {
	this.image = this.fluidImage;
    }

    /**
     * move the character, depending on keyinput
     * */
    public void move() {

	float tempx = x;
	float tempy = y;

	// move the player
	x += dx;
	y += dy;

	// check if cube is leaving the window
	if (x < 0 | x > panelWidth - width)
	    x = tempx;
	if (y < 0 | y > panelHeight - height)
	    y = tempy;

	// check if cube collides with anything
	// if true: revert everything

	if (gamepanel.checkCollisions()) {
	    x = tempx;
	    y = tempy;
	}
	// if (gamepanel.getDetector().isCollision()) {
	// x = tempx;
	// y = tempy;
	// }

    }

    public void setImage(Image image) {
	this.image = image;
    }

    /**
     * @return the x-Position
     */
    public float getX() {
	return x;
    }

    /**
     * @return the y-Position
     */
    public float getY() {
	return y;
    }

    /**
     * @param x
     *            the x to set
     */
    public void setX(float x) {
	this.x = x;
    }

    /**
     * @param y
     *            the y to set
     */
    public void setY(float y) {
	this.y = y;
    }

    /**
     * @return the image
     */
    public Image getImage() {
	return image;
    }

    /**
     * called when key is pressed
     * */
    public void keyPressed(KeyEvent e) {
	this.isMoving = true;
	int key = e.getKeyCode();

	if (key == KeyEvent.VK_LEFT)
	    dx = -0.5f;

	if (key == KeyEvent.VK_RIGHT)
	    dx = 0.5f;

	if (key == KeyEvent.VK_UP && currentState != FLUID)
	    dy = -0.5f;

	if (key == KeyEvent.VK_DOWN && currentState != AERIAL)
	    dy = 0.5f;

	// jump only in aerial state!!
	// if (key == KeyEvent.VK_SPACE && isAerial)
	// dy = -5;

	// temperature control++++++++++++++++++
	if (key == KeyEvent.VK_A) {
	    if (gamepanel.getAggregateChanges() < gamepanel
		    .getMaxAggregateChanges()) {

		if (currentState != HARD)
		    makeHard(false);
	    }
	}

	if (key == KeyEvent.VK_S) {

	    if (gamepanel.getAggregateChanges() < gamepanel
		    .getMaxAggregateChanges()) {

		if (currentState != FLUID) {
		    makeFluid();
		}

	    }

	}

	if (key == KeyEvent.VK_D) {

	    if (gamepanel.getAggregateChanges() < gamepanel
		    .getMaxAggregateChanges()) {
		if (currentState != AERIAL) {
		    this.makeAerial();
		}
	    }
	}
    }

    private void updateAggregateChanges() {
	gamepanel.setAggregateChanges(gamepanel.getAggregateChanges() + 1);
	gamepanel.updateText();
    }

    /**
     * called when key is released
     * */
    public void keyReleased(KeyEvent e) {
	this.isMoving = false;

	int key = e.getKeyCode();

	if (key == KeyEvent.VK_LEFT) {
	    dx = 0;
	   // this.slideLeft = true;
	}

	if (key == KeyEvent.VK_RIGHT) {
	    dx = 0;
	   // this.slideRight = true;
	}

	if (key == KeyEvent.VK_UP)
	    dy = 0;

	if (key == KeyEvent.VK_DOWN)
	    dy = 0;

	// if (key == KeyEvent.VK_SPACE)
	// dy = 0;

    }

    public boolean isMoving() {
	return isMoving;
    }

    public void setMoving(boolean isMoving) {
	this.isMoving = isMoving;
    }

    public void slideLeft(int startvalue) {
	dx = startvalue;
    }

    /**
     * @return the rectangle framing the icecube, needed for collision detection
     * */
    public Rectangle getBounds() {
	return new Rectangle((int) x, (int) y, width, height);
    }

    public int getWidth() {
	return width;
    }

    public void setWidth(int width) {
	this.width = width;
    }

    public int getHeight() {
	return height;
    }

    public void setHeight(int height) {
	this.height = height;
    }

    /**
     * @return the isHard
     */
    public boolean isHard() {
	return currentState == HARD;
    }

    /**
     * @return the isFluid
     */
    public boolean isFluid() {
	return currentState == FLUID;
    }

    /**
     * @return the isAerial
     */
    public boolean isAerial() {
	return currentState == AERIAL;
    }

    /**
     * @param panelWidth
     *            the panelWidth to set. needed for move player's move radius
     */
    public void setPanelWidth(int panelWidth) {
	this.panelWidth = panelWidth;
    }

    /**
     * @param panelHeight
     *            the panelHeight to set needed for move player's move radius
     */
    public void setPanelHeight(int panelHeight) {
	this.panelHeight = panelHeight;
    }

    /**
     * needed for "time to fly"
     * */
    public void run() {

	while (true) {
	    while (currentState == AERIAL) {

		if (timetofly <= 0) {

		    makeHard(true);
		}
		timetofly--;
		// WARNING: DON'T REMOVE THIS LINE:
		System.out.println("timetofly == " + timetofly);
	    }
	    try {
		Thread.sleep(100);
	    } catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	    }
	}
    }

}
